/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kuti.grp5;

import kuti.ISimulParams;

/**
 * @author Marc Schorderet <marc.schorderet@edu.hefr.ch>
 * @author Vincenzo Do <vincenzo.do@edu.hefr.ch>
 * @version 1.0
 * 
 * @see ISimulParams
 */

public class SimulParams implements ISimulParams {
    

    private double kDiameter;
    private double kMaxEnergy;
    private double kInitialEnergy;
    private double kSpeedCutterOn;
    private double kSpeedCutterOff;
    private double kMovingEnergy;
    private double kRotationEnergy;
    private double kCutterEnergy;
    private double radarNoiseFactor;
    private long maxSimulationSteps;
    private double radarEnergy;
    private int messageLength;
    private int scoreEvalInterval;
    private double magnetLiberationEnergy;
    private int bladeGrowthPeriod;
    private int bladeMax;
    

    /**
     * 
     * @param kDiameter                 Diameter of the Kuti
     * @param kMaxEnergy                Max energy of the Kuti
     * @param kInitialEnergy            Initial energy of the Kuti
     * @param kSpeedCutterOn            Speed of the Kuti with cutter on
     * @param kSpeedCutterOff           Speed of the Kuti with cutter off
     * @param kMovingEnergy             Moving energy of the Kuti
     * @param kRotationEnergy           Rotation energy of the Kuti
     * @param kCutterEnergy             Cutter energy of the Kuti
     * @param radarNoiseFactor           Nose factor of the radar
     * @param maxSimulationSteps        max steps of the simulation
     * @param radarEnergy               radar energy
     * @param messageLength             length of the message
     * @param scoreEvalInterval         interval of the score evaluation
     * @param magnetLiberationEnergy    magnet liberation energy
     * @param bladeGrowthPeriod         blade growth period
     * @param bladeMax                  max blade height
     */
    
    public SimulParams(double kDiameter, double kMaxEnergy, double kInitialEnergy, double kSpeedCutterOn, double kSpeedCutterOff, double kMovingEnergy, double kRotationEnergy, double kCutterEnergy, double radarNoseFactor, long maxSimulationSteps, double radarEnergy, int messageLength, int scoreEvalInterval, double magnetLiberationEnergy, int bladeGrowthPeriod, int bladeMax) {
        

        this.kDiameter = kDiameter;
        this.kMaxEnergy = kMaxEnergy;
        this.kInitialEnergy = kInitialEnergy;
        this.kSpeedCutterOn = kSpeedCutterOn;
        this.kSpeedCutterOff = kSpeedCutterOff;
        this.kMovingEnergy = kMovingEnergy;
        this.kRotationEnergy = kRotationEnergy;
        this.kCutterEnergy = kCutterEnergy;
        this.radarNoiseFactor = radarNoseFactor;
        this.maxSimulationSteps = maxSimulationSteps;
        this.radarEnergy = radarEnergy;
        this.messageLength = messageLength;
        this.scoreEvalInterval = scoreEvalInterval;
        this.magnetLiberationEnergy = magnetLiberationEnergy;
        this.bladeGrowthPeriod = bladeGrowthPeriod;
        this.bladeMax = bladeMax;
        
        //Check parameters validity
        this.parametersCheck();
        
    }
    
    
    
    
    /**
     * 
     * @return Returns the diameter of the Kuti.
     */
    
    @Override
    public double getKDiameter() {
        return kDiameter;
    }

    /**
     * 
     * @return Returns the max energy of the Kuti.
     */
    
    @Override
    public double getKMaxEnergy() {
        return kMaxEnergy;
    }

    /**
     * 
     * @return Returns the initial energy of the Kuti.
     */
    
    @Override
    public double getKInitialEnergy() {
        return kInitialEnergy;
    }

    /**
     * 
     * @param cutterOn  True if the cutter is on, else false.
     * 
     * @return Return the speed of the Kuti.
     */
    
    @Override
    public double getKSpeed(boolean cutterOn) {
        return (cutterOn) ? kSpeedCutterOn : kSpeedCutterOff;
    }
    
    /**
     * 
     * @return Returns the moving energy of the kuti.
     */

    @Override
    public double getKMovingEnergy() {
        return kMovingEnergy;
    }

    /**
     * 
     * @return Returns the rotation energy of the Kuti.
     */
    
    @Override
    public double getKRotationEnergy() {
        return kRotationEnergy;
    }

    /**
     * 
     * @return Returns the cutter energy of the kuti. 
     */
    
    @Override
    public double getKCutterEnergy() {
        return kCutterEnergy;
    }

    /**
     * 
     * @return Returns the Noise factor of the radar.
     */
    
    @Override
    public double getRadarNoiseFactor() {
        return radarNoiseFactor;
    }

    /**
     * 
     * @return Returns the energy that uses the kuti when he using radar.
     */
    
    @Override
    public double getRadarEnergy() {
        return radarEnergy;
    }

    /**
     * 
     * @return Returns the length of the message.
     */
    
    @Override
    public int getMessageLength() {
        return messageLength;
    }
    
    /**
     * 
     * @return Returns the max length of a blade of grass.
     */

    @Override
    public int getBladeHMax() {
        return bladeMax;
    }

    /**
     * 
     * @return Returns the growth period of a blade of grass.
     */
    
    @Override
    public int getBladeGrowthPeriod() {
        return bladeGrowthPeriod;
    }

    /**
     * 
     * @return Returns the energy that the kuti needs to liberate for a magnet 
     *  obstacle.
     */
    
    @Override
    public double getMagnetLiberationEnergy() {
        return magnetLiberationEnergy;
    }

    /**
     * 
     * @return Returns the interval of score evaluation.
     */
    
    @Override
    public int getScoreEvalInterval() {
        return scoreEvalInterval;
    }

    /**
     * 
     * @return Returns the max steps of the simulation.
     */
    
    @Override
    public long getMaxSimulationSteps() { 
        return maxSimulationSteps;
    }
    
    //To check parameters validity
    private void parametersCheck() {
        if (this.kDiameter < 10 | this.kDiameter > 100) {
            throw new IllegalArgumentException("The value attributed to kDiameter must be in range (10<x<100)");
        }
        if (this.kMaxEnergy < 100 | this.kMaxEnergy > 100000) {
            throw new IllegalArgumentException("The value attributed to kMaxEnergy must be in range (100<x<100000)");
        }
        if ((this.kInitialEnergy < (this.kMaxEnergy / 10)) | (this.kInitialEnergy > (this.kMaxEnergy))) {
            throw new IllegalArgumentException("The value attributed to kInitialEnergy must be in range (maxEnergy/10)<x<maxEnergy");
        }

        if (this.kSpeedCutterOn < 1 | this.kSpeedCutterOn > 100) {
            throw new IllegalArgumentException("The value attributed to kSpeedCutterOn must be in range (1<x<100)");
        }
        if (this.kSpeedCutterOff < 1 | this.kSpeedCutterOff > 100) {
            throw new IllegalArgumentException("The value attributed to kSpeedCutterOff must be in range (1<x<100)");
        }

        if ((this.kMovingEnergy < (this.kMaxEnergy / 100000)) | (this.kMovingEnergy > (this.kMaxEnergy / 100))) {
            throw new IllegalArgumentException("The value attributed to kMovingEnergy must be in range (maxEnergy/100000<x<maxEnergy/100)");
        }

        if ((this.kRotationEnergy < (this.kMovingEnergy / 1000)) | (this.kRotationEnergy > (this.kMovingEnergy))) {
            throw new IllegalArgumentException("The value attributed to kRotationEnergy must be in range (movEnergy/1000<x<movEnergy)");
        }

        if ((this.kCutterEnergy > (this.kMaxEnergy / 100) | this.kCutterEnergy < 0)) {
            throw new IllegalArgumentException("The value attributed to kCutterEnergy must be in range (0<x<maxEnergy/100)");
        }

        if (this.radarNoiseFactor < 0.01 | this.radarNoiseFactor > 0.5) {
            throw new IllegalArgumentException("The value attributed to radarNoiseFactor must be in range (0.01<x<0.5)");
        }

        if ((this.radarEnergy > (this.kMaxEnergy / 100) | this.radarEnergy < 0)) {
            throw new IllegalArgumentException("The value attributed to radarEnergy must be in range (0<x<maxEnergy/100)");
        }

        if (this.messageLength < 100 | this.messageLength > 10000) {
            throw new IllegalArgumentException("The value attributed to messageLength must be in range (100<x<10000)");
        }

        if (this.bladeMax < 5 | this.bladeMax > 1000) {
            throw new IllegalArgumentException("The value attributed to bladeMax must be in range (5<x<1000)");
        }

        if (this.bladeGrowthPeriod < 1 | this.bladeGrowthPeriod > 10000) {
            throw new IllegalArgumentException("The value attributed to bladeGrowthPeriod must be in range (1<x<10000)");
        }

        if (this.scoreEvalInterval < 1 | this.scoreEvalInterval > 10000) {
            throw new IllegalArgumentException("The value attributed to scoreEvalInterval must be in range (1<x<10000)");
        }

        if ((this.magnetLiberationEnergy < (this.kMaxEnergy / 1000)) | (this.magnetLiberationEnergy > (this.kMaxEnergy / 10))) {
            throw new IllegalArgumentException("The value attributed to magnetLiberationEnergy must be in range (maxEnergy/1000<x<maxEnergy/10)");
        }

        if (this.maxSimulationSteps < 0 | this.maxSimulationSteps > 100000000) {
            throw new IllegalArgumentException("The value attributed to maxSimulationSteps must be in range (0<x<100000)");
        }
    }
    
}
